package com.gitee.apanlh.util.net.http;

import com.gitee.apanlh.util.dataformat.JsonUtils;
import com.gitee.apanlh.util.encode.CharsetCode;
import com.gitee.apanlh.util.valid.ValidParam;
import com.gitee.apanlh.web.http.HttpMethod;

import java.util.Map;

/**
 * 	HTTP工具类
 * 	<br>基于HttpClientBuilder封装基础HTTP调用
 * 	<br>如果需要使用更复杂的HTTP调用，则使用{@link HttpClientBuilder}类
 * 	#mark 方法重构
 *	@author Pan
 */
public class HttpUtils {
	
	/**
	 * 	构造函数
	 *
	 * 	@author Pan
	 */
	private HttpUtils() {
		//	不允许外部实例
		super();
	}
	
	/**
	 * 	GET请求(无参)
	 * 	
	 * 	@author Pan
	 * 	@param  url			请求地址
	 * 	@return	String	
	 */
	public static String sendGet(String url) {
		return sendGet(url, CharsetCode.UTF_8);
    }
	
	/**	
	 * 	GET请求(无参)
	 * 	<br>自定义返回字符集
	 * 	
	 * 	@author Pan	
	 * 	@param 	url			请求地址
	 * 	@param 	charset		字符集
	 * 	@return	String
	 */
	public static String sendGet(String url, String charset) {
		return sendGet(url, null, charset);
	}
    
    /**
     * 	GET请求(带参)
     * 	<br>例如: {@code ?name=123&phone=456}
     * 
     * 	@author Pan
	 *  @param  <V>     	值类型
     * 	@param  url			请求地址
     * 	@param  paramMap	请求参数
     * 	@return	String
     */
	public static <V> String sendGet(String url, Map<String, V> paramMap) {
		return sendGet(url, paramMap, CharsetCode.UTF_8);
	}
    
	/**	
	 * 	GET请求(带参)
	 * 	<br>例如: {@code ?name=123&phone=456}
	 * 	
	 * 	@author Pan
	 *  @param  <V>     	值类型
	 * 	@param 	url			请求地址
	 * 	@param 	paramMap	请求参数
	 * 	@param 	charset		字符集
	 * 	@return	String
	 */
	public static <V> String sendGet(String url, Map<String, V> paramMap, String charset) {
		return HttpClientBuilder.builder(url).withBodyForm(paramMap).withCharset(charset).build().getStr();
	}
	
	/**	
	 * 	GET请求(无参)
	 * 	<br>返回byte[]
	 * 	<br>可用于请求流相关
	 * 	
	 * 	@author Pan
	 * 	@param 	url		请求地址
	 * 	@return	byte[]
	 */
	public static byte[] sendGetToByte(String url) {
		return sendGetToByte(url, null);
    }
	
	/**	
	 * 	GET请求(无参)
	 * 	<br>返回byte[]
	 * 	<br>可用于请求流相关
	 * 	<br>自定义请求头
	 * 	
	 * 	@author Pan
	 * 	@param 	url				请求地址
	 * 	@param 	httpHeader		请求头对象
	 * 	@return	byte[]
	 */
	public static byte[] sendGetToByte(String url, HttpRequestHeader httpHeader) {
		return HttpClientBuilder.builder(url).withHeader(httpHeader).build().getByte();
    }
	
	/**		
	 * 	POST请求(空参数)
	 * 	<br>默认字符集UTF-8
	 * 	
	 * 	@author Pan
	 * 	@param 	url		请求地址
	 * 	@return	String
	 */
	public static String sendPost(String url) {
		return sendPost(url, null, null, null);
	}
	
	/**
	 * 	POST请求(带参)
	 * 	<br>请求参数格式为JSON
	 * 	<br>默认字符集UTF-8
	 * 	
	 * 	@author Pan
	 * 	@param 	url			请求地址
	 * 	@param 	jsonParam	JSON格式参数
	 * 	@return	String
	 */
	public static String sendPost(String url, String jsonParam) {
		return sendPost(url, null, jsonParam, null);
	}
	
	/**	
	 * 	POST请求(带参)
	 * 	<br>请求参数格式为JSON
	 * 	<br>默认字符集UTF-8
	 *  <br>自定义字符集
	 *  
	 * 	@author Pan
	 * 	@param 	url			请求地址
	 * 	@param 	jsonParam	JSON格式参数
	 * 	@param 	charset		字符集
	 * 	@return String
	 */
	public static String sendPost(String url, String jsonParam, String charset) {
		return sendPost(url, null, jsonParam, charset);
	}
	
	/**	
	 * 	POST请求(带参)
	 * 	<br>请求参数格式为JSON
	 * 	<br>自定义请求头
	 *  <br>自定义字符集
	 *  
	 * 	@author Pan
	 * 	@param 	url				请求地址
	 * 	@param 	httpHeader		请求头对象
	 * 	@param 	jsonParam		JSON格式参数
	 * 	@param 	charset			字符集
	 * 	@return	String
	 */
	public static String sendPost(String url, HttpRequestHeader httpHeader, String jsonParam, String charset) {
		return HttpClientBuilder.builder(url, HttpMethod.POST)
			.withHeader(httpHeader)
			.withBodyJson(jsonParam)
			.withCharset(charset)
		.build().getStr();
	}
	
	/**	
	 * 	POST请求(带参)
	 * 	<br>请求参数格式为JSON
	 * 	<br>默认字符集UTF-8
	 *  
	 * 	@author Pan
	 * 	@param  <T>      数据类型
	 * 	@param 	url			请求地址
	 * 	@param 	jsonParam	JSON格式参数
	 * 	@param 	clazz		转换对象
	 * 	@return T
	 */
	public static <T> T sendPostJsonToBean(String url, String jsonParam, Class<T> clazz) {
		return sendPostJsonToBean(url, null, jsonParam, CharsetCode.UTF_8, clazz);
	}
	
	/**	
	 * 	POST请求(带参)
	 * 	<br>请求参数格式为JSON
	 * 	<br>默认字符集UTF-8
	 *  <br>自定义字符集
	 *  
	 * 	@author Pan
	 * 	@param  <T>      数据类型
	 * 	@param 	url			请求地址
	 * 	@param 	jsonParam	JSON格式参数
	 * 	@param 	charset		字符集
	 * 	@param 	clazz		转换对象
	 * 	@return T
	 */
	public static <T> T sendPostJsonToBean(String url, String jsonParam, String charset, Class<T> clazz) {
		return sendPostJsonToBean(url, null, jsonParam, charset, clazz);
	}
	
	/**	
	 * 	POST请求(带参)
	 * 	<br>请求参数格式为JSON
	 * 	<br>默认字符集UTF-8
	 *  <br>自定义字符集
	 *  <br>自定义请求头
	 *  	
	 * 	@author Pan
	 * 	@param  <T>      数据类型
	 * 	@param 	url				请求地址
	 * 	@param 	httpHeader		请求头对象
	 * 	@param 	jsonParam		JSON格式参数
	 * 	@param 	charset			字符集
	 * 	@param 	clazz			转换对象
	 * 	@return	T
	 */
	public static <T> T sendPostJsonToBean(String url,  HttpRequestHeader httpHeader, String jsonParam, String charset, Class<T> clazz) {
		HttpResponse build = HttpClientBuilder.builder(url, HttpMethod.POST)
			.withHeader(httpHeader)
			.withBodyJson(jsonParam)
			.withCharset(charset)
		.build();
		
		String content = build.getStr();
		
		return ValidParam.isEmpty(content) ? null : JsonUtils.toBean(content, clazz);
	}
	
	/**	
	 * 	POST请求(带参)
	 * 	<br> 请求方式为NameValuePair格式(值对节点类型)
	 * 	<br> 非传递JSON格式
	 * 	<br> 例如:{@code name=123&phone=456}
	 * 	<br> 字符集默认为UTF-8
	 * 	
	 * 	@author Pan
	 *  @param  <V>     	值类型
	 * 	@param 	url			请求地址
	 * 	@param 	paramMap	请求参数
	 * 	@return	String
	 */
	public static <V> String sendPostForm(String url, Map<String, V> paramMap) {
		return sendPostForm(url, paramMap, CharsetCode.UTF_8);
	}
	
	/**
	 * 	POST请求(带参)
	 * 	<br> 请求方式为NameValuePair格式(值对节点类型)
	 * 	<br> 非传递JSON格式
	 * 	<br> 例如:{@code name=123&phone=456}
	 * 	<br> 自定义字符集
	 * 	
	 * 	@author Pan
	 *  @param  <V>     	值类型
	 * 	@param 	url			请求地址
	 * 	@param 	paramMap	请求参数
	 * 	@param 	charset		字符集
	 * 	@return	String
	 */
	public static <V> String sendPostForm(String url, Map<String, V> paramMap, String charset) {
		return HttpClientBuilder.builder(url, HttpMethod.POST).withBodyForm(paramMap).withCharset(charset).build().getStr();
	}
    
	/**
     * 	post请求(无参)
	 * 	<br>返回byte[]
	 * 	<br>可用于请求流相关
	 * 	<br>默认字符集UTF-8
	 * 	
     * 	@author Pan
     * 	@param  url			请求地址
     * 	@return	byte[]		
     */
	public static byte[] sendPostToByte(String url) {
    	return sendPostToByte(url, null, null, null);
	}
	
	/**
     * 	post请求(带参)
	 * 	<br>返回byte[]
	 * 	<br>可用于请求流相关
	 * 	
     * 	@author Pan
     * 	@param  url			请求地址
     * 	@param  jsonParam	请求参数
     * 	@param  charset		字符集
     * 	@return	byte[]		
     */
	public static byte[] sendPostToByte(String url, String jsonParam, String charset) {
    	return sendPostToByte(url, null, jsonParam, charset);
	}
	
	/**
     * 	post请求(带参)
	 * 	<br>返回byte[]
	 * 	<br>可用于请求流相关
	 * 	
     * 	@author Pan
     * 	@param  url				请求地址
     * 	@param  httpHeader		请求头对象
     * 	@param  jsonParam		请求参数
     * 	@param  charset			字符集
     * 	@return	byte[]		
     */
	public static byte[] sendPostToByte(String url, HttpRequestHeader httpHeader, String jsonParam, String charset) {
    	return sendToByte(url, HttpMethod.POST, httpHeader, jsonParam, charset);
	}
	
	/**	
     * 	GET以及POST通用封装
     * 	<br> 用于请求或接受流
     * 	<br> 返回byte[]
     * 
     * 	@author Pan
     * 	@param 	url				请求地址
     * 	@param 	method			请求方法
     * 	@param 	httpHeader		请求头对象
     * 	@param 	jsonParam		请求参数
     * 	@param 	charset			请求参数字符集
     * 	@return byte[]
     */
    private static byte[] sendToByte(String url, HttpMethod method, HttpRequestHeader httpHeader, String jsonParam, String charset) {
    	return HttpClientBuilder.builder(url, method)
			.withBodyJson(jsonParam)
			.withHeader(httpHeader)
			.withCharset(charset)
		.build().getByte();
    }
}
